package xyz.yuzegod.megawalls;

import com.google.common.io.ByteArrayDataOutput;
import com.google.common.io.ByteStreams;
import fr.minuskube.inv.InventoryManager;
import org.bukkit.Bukkit;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.bukkit.metadata.FixedMetadataValue;
import org.bukkit.plugin.Plugin;
import org.bukkit.plugin.java.JavaPlugin;
import xyz.yuzegod.megawalls.classes.Classes;
import xyz.yuzegod.megawalls.classes.ClassesManager;
import xyz.yuzegod.megawalls.command.CommandHandler;
import xyz.yuzegod.megawalls.config.FileConfig;
import xyz.yuzegod.megawalls.database.DataBase;
import xyz.yuzegod.megawalls.database.KeyValue;
import xyz.yuzegod.megawalls.game.FakePlayer;
import xyz.yuzegod.megawalls.game.Game;
import xyz.yuzegod.megawalls.game.GamePlayer;
import xyz.yuzegod.megawalls.listener.*;
import xyz.yuzegod.megawalls.stats.SQLSettings;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;

public class MegaWalls extends JavaPlugin
{
    private static final Random random;
    private static long activeMode;
    private static MegaWalls instance;
    private FileConfig config;
    private CommandHandler commandHandler;
    private InventoryManager inventoryManager;
    private DataBase database;
    private Game game;
    
    public MegaWalls() {
        this.game = null;
    }
    
    public static List<GamePlayer> getIngame() {
        final List<GamePlayer> gamePlayers = new ArrayList<GamePlayer>();
        for (final GamePlayer gamePlayer : GamePlayer.getGamePlayers()) {
            if (gamePlayer.isOnline()) {
                if (gamePlayer.isSpectator()) {
                    continue;
                }
                gamePlayers.add(gamePlayer);
            }
        }
        return gamePlayers;
    }
    
    public static MegaWalls getInstance() {
        return MegaWalls.instance;
    }
    
    public static boolean isActiveMode() {
        return System.currentTimeMillis() < MegaWalls.activeMode;
    }
    
    public static void updateRejoin(final GamePlayer gamePlayer, final String server, final long time) {
        final DataBase database = getInstance().getDataBase();
        if (!database.isValueExists("megawalls_rejoin", SQLSettings.KV_REJOIN, new KeyValue("uuid", gamePlayer.getUuid().toString()))) {
            database.dbInsert("megawalls_rejoin", new KeyValue("uuid", gamePlayer.getUuid().toString()).add("realname", gamePlayer.getName()).add("server", server).add("time", time));
            return;
        }
        database.dbUpdate("megawalls_rejoin", new KeyValue("server", server).add("time", time), new KeyValue("uuid", gamePlayer.getUuid().toString()));
    }
    
    public void onLoad() {
    }
    
    public void onDisable() {
        try {
            if (this.game != null && this.game.isStarted()) {
                this.game.onStop();
            }
            if (this.database != null) {
                this.database.close();
            }
            for (final FakePlayer fakePlayer : FakePlayer.fakePlayerMap.values()) {
                fakePlayer.delete();
            }
        }
        catch (Exception ex) {}
    }
    
    public static String getMetadataValue() {
        return "MegaWalls";
    }
    
    public FileConfig getConfig() {
        return this.config;
    }
    
    public DataBase getDataBase() {
        return this.database;
    }
    
    public void tpToLobby(final Player p) {
        try {
            final ByteArrayDataOutput buf = ByteStreams.newDataOutput();
            buf.writeUTF("Connect");
            buf.writeUTF(this.getConfig().getString("lobby"));
            p.sendPluginMessage((Plugin)this, "BungeeCord", buf.toByteArray());
        }
        catch (Exception ex) {}
    }
    
    public static FixedMetadataValue getFixedMetadataValue() {
        return new FixedMetadataValue((Plugin)MegaWalls.instance, (Object)true);
    }
    
    public void setGame(final Game game) {
        if (game == null) {
            return;
        }
        this.game = game;
        new BlockListener(this);
        new EntityListener(this);
        new PlayerListener(this);
        new ServerListener(this);
        new InventoryListener(this);
        new EffectListener(this);
    }
    
    public static KeyValue getRejoin(final GamePlayer gamePlayer) {
        final DataBase database = getInstance().getDataBase();
        if (database.isValueExists("megawalls_rejoin", SQLSettings.KV_REJOIN, new KeyValue("uuid", gamePlayer.getUuid().toString()))) {
            String server = "";
            String time = "0";
            for (KeyValue kv : database.dbSelect("megawalls_rejoin", SQLSettings.KV_REJOIN, new KeyValue("uuid", gamePlayer.getUuid().toString()))) {
                server = kv.getString("server");
                time = kv.getString("time");
            }
            return new KeyValue("server", server).add("time", time);
        }
        return null;
    }
    
    public void onEnable() {
        MegaWalls.instance = this;
        this.config = new FileConfig((Plugin)this);
        this.commandHandler = new CommandHandler();
        (this.inventoryManager = new InventoryManager(this)).init();
        this.getServer().getMessenger().registerOutgoingPluginChannel((Plugin)this, "BungeeCord");
        ClassesManager.registerAll();
        xyz.yuzegod.megawalls.inventory.InventoryManager.registerAll();
        if (!this.config.getBoolean("setup", false)) {
            new SetupListener(this);
            return;
        }
        (this.database = DataBase.create(this.getConfig().getConfigurationSection("database"))).createTables("megawalls_stats", SQLSettings.KV_STATS, null);
        this.database.createTables("megawalls_effects", SQLSettings.KV_EFFECTS, null);
        this.database.createTables("spectator_settings", SQLSettings.KV_SPECTATOR_SETTINGS, null);
        this.database.createTables("megawalls_challenges", SQLSettings.KV_CHALLENGES, null);
        this.database.createTables("megawalls_rejoin", SQLSettings.KV_REJOIN, null);
        for (final Classes classes : ClassesManager.getClasses()) {
            this.database.createTables("classes_" + classes.getName(), SQLSettings.KV_CLASSES, null);
        }
        Game.build(new FileConfig((Plugin)this, "game.yml"), (CommandSender)Bukkit.getConsoleSender());
    }
    
    public static Random getRandom() {
        return MegaWalls.random;
    }
    
    public static long getActiveMode() {
        return MegaWalls.activeMode;
    }
    
    public static void setActiveMode(final long activeMode) {
        MegaWalls.activeMode = activeMode;
    }
    
    public CommandHandler getCommandHandler() {
        return this.commandHandler;
    }
    
    public InventoryManager getInventoryManager() {
        return this.inventoryManager;
    }
    
    public Game getGame() {
        return this.game;
    }
    
    static {
        random = new Random();
        MegaWalls.activeMode = System.currentTimeMillis();
    }
}
